package game.common.components.base{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import game.data.constant.name.BehaviorName;
	import game.data.constant.name.RoleName;
	import game.data.constant.state.Direction;
	import game.data.structure.animation.Animation;
	import game.data.structure.animation.AnimationData;
	import game.data.structure.animation.FrameData;
	import game.data.structure.role.RoleData;
	import game.model.animation.AnimationModel;
	
	import lib.gameEngine.core.Model;
	
	/**
	 * 显示元素类
	 *  
	 * 本类是所有角色及怪物的显示基类
	 * 
	 * 本类中定义了角色与怪物的基本行为，例如：
	 * 
	 * 行走，战斗，呐喊等等。但是具体实现并不在此。
	 * 
	 * 
	 * 
	 *  
	 * 附言：对于该类的基类我纠结了好久，因为使用Sprite性能较低，但是如果使用Bitmap作为基类，
	 * 
	 * 那么实现鼠标事件也是一件痛苦的事情。暂时先使用Sprite，后期再深入研究与优化。
	 * 
	 * 
	 * @author Sunix
	 * 
	 */	
	public class DisplayElement extends Sprite{
		
		private var _aniResPool:Object;  //动画资源池
		private var _behavior:String = BehaviorName.WAIT;    //角色当前行为，默认值为待机
		private var _currentFrameNum:uint = 0;  //当前动作帧号
		private var _loop:Boolean = false;     //动画循环标志，默认为不循环
		//private var _data:RoleData;             //角色数据信息
		private var _isExist:Boolean = false;  //是否存在于舞台之上，本标志位于以后的资源回收利用相关
		private var _currentFrameIndex:uint = 0;  //当前帧号
		private var _animationData:AnimationData; //当前动作数据
		private var _bitmap:Bitmap;          //当前动作容器
		private var _frame:FrameData;       //当前帧数据
		private var _frames:Array;          //当前朝向的帧数据组，次属性为缓存属性；
		private var _direction:String = Direction.FRONT;      //朝向，默认为正向
		private var _model:Model;  //数据持有者的引用，本处用于优化测试  TODO
		
		/**
		 * 构造函数
		 *  
		 * 
		 * 
		 */		
		public function DisplayElement(){
			init();
		}
		
		public function get model():Model	{
			return _model;
		}

		public function set model(value:Model):void{
			_model = value;
		}

		public function get direction():String{
			return _direction;
		}

		public function set direction(value:String):void{
			_direction = value;
			_frames =  _animationData.frames[_direction];
		}

		/**
		 * 设置用户的行为
		 * 
		 *  
		 * @param str 行为名称，具体行为名称请参见BehaviorName类
		 * 
		 */		
		public function set behavior(str:String):void{
			_behavior = str;
			var animation:Animation = (_model as AnimationModel).animationPool[RoleName.ROLE];
			_animationData = animation.getAnimationData(str);
		}
		
		/**
		 * 设置角色的数据
		 * 
		 *  
		 * @param rd 角色数据
		 * 
		 */		
/*		public function set data(rd:RoleData):void{
			_data = rd;
		}*/
		
		/**
		 * 设置当前动作是否循环播放
		 * 
		 *  
		 * @param bool  是否循环播放
		 * 
		 */		
		public function set loop(bool:Boolean):void{
			_loop = bool
		}
		
		/**
		 * 播放
		 * 
		 * 本函数由相应的View对象在监听到EnterFrame通知后调用
		 * 
		 *  
		 * TODO 此处可能需要有补帧行为，暂时没想明白，放弃
		 */		
		public function play():void{
			_frame = _frames[_currentFrameIndex];
			//位图缓存处理，极大提高性能
			if(!_frame.bitmapData){
				_frame.bitmapData = new BitmapData(_frame.width,_frame.height,true,0x00000000);
				var bmd:BitmapData = new (_model as AnimationModel).resClass();
				_frame.bitmapData.copyPixels(bmd,new Rectangle(_frame.point.x,_frame.point.y,_frame.width,_frame.height),new Point(0,0) ,null,null,true);
			}
			_bitmap.bitmapData = _frame.bitmapData;
			_currentFrameIndex++;
			if(_currentFrameIndex>_frames.length-1)_currentFrameIndex = 0;
			positionHandle();
		}
		
		private function positionHandle():void{  //动作的偏移量处理
			_bitmap.x = 0;
			_bitmap.y = 0;
			_bitmap.x = - (_bitmap.x +  _frame.offsetPoint.x);
			_bitmap.y = - (_bitmap.y +  _frame.offsetPoint.y);
		}
		
		private function init():void{  //初始化函数
			this.x = Math.random() * 500;
			this.y = Math.random() * 500;
			this.addEventListener(Event.ADDED_TO_STAGE,onAddToStage);
			_bitmap = new Bitmap();
			this.addChild(_bitmap);
		}
		
		private function onAddToStage(e:Event):void{   //添加到舞台
			this.removeEventListener(Event.ADDED_TO_STAGE,onAddToStage);
			this.addEventListener(Event.REMOVED_FROM_STAGE,onRemoveFromStage);
			_isExist = true;
		}
		
		private function onRemoveFromStage(e:Event):void{  //从舞台被移除
			this.removeEventListener(Event.REMOVED_FROM_STAGE,onRemoveFromStage);
			this.addEventListener(Event.ADDED_TO_STAGE,onAddToStage);
			_isExist = false;
		}
	}
}